package com.educate.ucenter.rpc.provide.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.educate.common.utils.converter.ListUtils;
import com.educate.common.utils.exception.AppException;
import com.educate.common.web.BeanUtils;
import com.educate.ucenter.dao.FamilyDao;
import com.educate.ucenter.dao.FamilyMemberDao;
import com.educate.ucenter.model.bo.FamilyBO;
import com.educate.ucenter.model.bo.FamilyMemberBO;
import com.educate.ucenter.model.po.Family;
import com.educate.ucenter.model.po.FamilyMember;
import com.educate.ucenter.rpc.api.FamilyService;
import lombok.extern.log4j.Log4j2;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Page;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Log4j2
@Service(
        version = "${api.service.version}",
        application = "${dubbo.application.id}",
        protocol = "${dubbo.protocol.id}",
        registry = "${dubbo.registry.id}"
)
public class FamilyServiceImpl implements FamilyService {

    @Resource FamilyDao familyDao;
    @Resource FamilyMemberDao familyMemberDao;

    @Override
    public void create(FamilyBO bo) {
        bo.setFamilyId(new ObjectId().toHexString());
        bo.setCreateTime(new Date());
        if (bo.getChildIds() == null) {
            bo.setChildIds(new ArrayList<>());
        }
        FamilyMember familyMember = new FamilyMember();
        familyMember.setUserId(bo.getCreator());
        familyMember.setFamilyId(bo.getFamilyId());
        addFamilyMember(familyMember);
        bo.setMemberNumber(1);
        familyDao.insert(bo);
    }

    @Override
    public void delete(FamilyBO bo) {
        familyDao.delete(bo);
    }

    @Override
    public void delete(String familyId) {
        familyDao.deleteById(familyId);
    }

    @Override
    public FamilyBO detail(String familyId) {
        Optional<Family> optional = familyDao.findById(familyId);
        if (!optional.isPresent()) {
            throw new AppException("不存在的实例");
        }
        return new FamilyBO(optional.get());
    }

    @Override
    public FamilyBO detail(FamilyBO bo) {
//        return detail(bo.getOrganizationId());
        return null;
    }

    @Override
    public void update(FamilyBO bo) {
        Optional<Family> optional = familyDao.findById(bo.getFamilyId());
        if (!optional.isPresent()) {
            throw new AppException("不存在的实例");
        }
        BeanUtils.copyPropertiesNonEmpty(bo, optional.get());
        familyDao.save(optional.get());
    }

    @Override
    public Page<FamilyBO> query(FamilyBO bo) {
        return familyDao.query(bo, bo.pageable()).map(FamilyBO::new);
    }

    @Override
    public List<FamilyBO> list(FamilyBO bo) {
        List<Family> result = familyDao.findAll();
        return ListUtils.map(result, FamilyBO::new);
    }

    @Override
    public List<FamilyBO> mine(FamilyMemberBO bo) {
        return familyMemberDao.findByUserId(bo.getUid())
                .stream()
                .map(familyMember -> familyDao.findById(familyMember.getFamilyId())
                        .map(FamilyBO::new)
                        .orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    @Override
    public void addFamilyMember(FamilyMember familyMember) {
        boolean exists = familyMemberDao.existsByUserIdAndFamilyId(familyMember.getUserId(), familyMember.getFamilyId());
        if (exists) throw new AppException("你已经是该家庭的成员了");
        familyMember.setCreateTime(new Date());
        familyMemberDao.insert(familyMember);
    }


    @Override
    public FamilyBO getOrCreateDefFamily(String user) {
        return familyDao.findByCreator(user)
                .map(FamilyBO::new)
                .orElseGet(() -> {
                    FamilyBO familyBO = new FamilyBO();
                    familyBO.setCreator(user);
                    create(familyBO);
                    return familyBO;
                });

    }

    @Override
    public void childMaster(FamilyBO bo) {
        familyDao.findById(bo.getFamilyId())
                .filter(family -> bo.getChildId().equals(family.getChildId()))
                .ifPresent(family -> familyDao.save(bo));
    }

    @Override
    public void memberAdd(FamilyMemberBO bo) {
        Family family = familyDao.findById(bo.getFamilyId())
                .orElseThrow(() -> new AppException("该家庭组不存在"));
        addFamilyMember(bo);
        family.setMemberNumber(family.getMemberNumber() + 1);
        familyDao.save(family);
    }

    @Override
    public List<FamilyMemberBO> members(FamilyBO bo) {
        Family family = familyDao.findById(bo.getFamilyId())
                .orElseThrow(() -> new AppException("该家庭组不存在"));
        return familyMemberDao.findByFamilyId(bo.getFamilyId())
                .stream()
                .map(FamilyMemberBO::new)
                .peek(familyMemberBO -> familyMemberBO.setAdmin(familyMemberBO.getUserId().equals(family.getCreator())))
                .collect(Collectors.toList());
    }

    @Override
    public void memberUpdate(FamilyMemberBO bo) {
        familyMemberDao.findByFamilyIdAndUserId(bo.getFamilyId(), bo.getUserId())
                .filter(familyMember -> !bo.getEpithet().equals(familyMember.getEpithet()))
                .ifPresent(familyMember -> {
                    familyMember.setEpithet(bo.getEpithet());
                    familyMemberDao.save(familyMember);
                });
    }
}
